﻿using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;

namespace ToolUtil
{
    enum CheckState
    {
        选中,
        不勾选,
        部分被选,
        禁用
    }
    /// <summary>
    /// 本类复写TreeView，实现了复选框的三态功能，且每个节点能够被禁用
    /// 使用方法：
    /// 勾选一个节点，将其ToolTipsText 设置为“1”
    /// 取消勾选一个节点，将其ToolTipsText 设置为“2”
    /// 部分勾选一个节点，将其ToolTipsText 设置为“3”
    /// 禁用某个节点(不勾选)，将其ForeColor设置为 Color.gray
    /// </summary>
    public class MyTreeView : System.Windows.Forms.TreeView
    {
        private Brush b = null;//节点字体颜色  
        private Point p;//画CheckBox的位置  
        public MyTreeView()
        {
            this.DrawMode = TreeViewDrawMode.OwnerDrawText;//自己画文本  
        }
        protected override void OnDrawNode(DrawTreeNodeEventArgs e)
        {
            b = Brushes.Black;//默认字体为黑色  
            if (e.Node.ForeColor == Color.Gray)
            {
                drawCheckBox(CheckState.禁用, e);
            }
            else//画可选择框
            {
                switch (e.Node.ToolTipText)
                {
                    case ("1"):
                        drawCheckBox(CheckState.选中, e);
                        break;
                    case "2":
                        drawCheckBox(CheckState.不勾选, e);
                        break;
                    case "3":
                        drawCheckBox(CheckState.部分被选, e);
                        break;
                    default:
                        break;
                }
            }

            if ((e.State & TreeNodeStates.Focused) != 0)
            {
                b = Brushes.White;//点击某节点时节点字体颜色为白色  
            }
            if (e.Bounds.X > 0)//未知BUG，会出现X=-1的情况，排除之
                e.Graphics.DrawString(e.Node.Text, this.Font, b, e.Bounds.Location);//画文本  
            TreeNode t = new TreeNode();
        }
        private void drawCheckBox(CheckState cs, DrawTreeNodeEventArgs e)
        {
            switch (cs)
            {
                case CheckState.选中:
                    p = e.Bounds.Location;//获取节点的位置  
                    p.X = p.X - 12;//覆盖到默认画CheckBox的位置  
                    CheckBoxRenderer.DrawCheckBox(e.Graphics, p, CheckBoxState.CheckedNormal);//画一个选中的CheckBox  
                    break;
                case CheckState.不勾选:
                    p = e.Bounds.Location;//获取节点的位置  
                    p.X = p.X - 12;//覆盖到默认画CheckBox的位置  
                    CheckBoxRenderer.DrawCheckBox(e.Graphics, p, CheckBoxState.UncheckedNormal);//画一个不选中的CheckBox  
                    break;
                case CheckState.部分被选:
                    p = e.Bounds.Location;//获取节点的位置  
                    p.X = p.X - 12;//覆盖到默认画CheckBox的位置  
                    CheckBoxRenderer.DrawCheckBox(e.Graphics, p, CheckBoxState.MixedNormal);//画一个部分选中的CheckBox  
                    break;
                case CheckState.禁用:
                    p = e.Bounds.Location;//获取节点的位置  
                    p.X = p.X - 12;//覆盖到默认画CheckBox的位置  
                    CheckBoxRenderer.DrawCheckBox(e.Graphics, p, CheckBoxState.UncheckedDisabled);//画一个禁用的选中的CheckBox  
                    b = Brushes.Gray;//当前节点字体为灰色  
                    break;
                default:
                    break;
            }
        }
    }
}
